home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
usenet
/
sources
/
volume89
/
unix
/
shel303a.1
< prev
next >
Wrap
Internet Message Format
|
1989-05-18
|
64KB
Path: xanth!ames!apple!sun!swap!page
From: page%swap@Sun.COM (Bob Page)
Newsgroups: comp.sources.amiga
Subject: v89i149: shell - csh-like shell v3.03a, Part01/02
Message-ID: <105698@sun.Eng.Sun.COM>
Date: 18 May 89 19:28:32 GMT
Sender: news@sun.Eng.Sun.COM
Lines: 2805
Approved: page@sun.com
Submitted-by: PERUGIA@ICNUCEVM.Bitnet (Cesare Dieni)
Posting-number: Volume 89, Issue 149
Archive-name: unix/shell303a.1
New to 3.03A:
- New filter commands fltlower, fltupper.
- Added configuration file feature: now if you have a file
named S:.login, it will be sourced for every Shell you start.
- New option dir -c.
- New editing feature: shift-left(right) arrow move cursor to
previous(next) word.
- Bugs fixed: alias command wasn't listed in help; typing a number
as a command was interpreted like 'alias'.
# This is a shell archive.
# Remove anything above and including the cut line.
# Then run the rest of the file through 'sh'.
# Unpacked files will be owned by you and have default permissions.
#----cut here-----cut here-----cut here-----cut here----#
#!/bin/sh
# shar: SHell ARchive
# Run the following text through 'sh' to create:
# comm1.c
# comm2.c
# comm3.c
# execom.c
# This is archive 1 of a 2-part kit.
# This archive created: Thu May 18 12:17:53 1989
echo "extracting comm1.c"
sed 's/^X//' << \SHAR_EOF > comm1.c
X/*
X * COMM1.C
X *
X * Matthew Dillon, August 1986
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X *
X * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89
X *
X */
X
Xextern char *v_passed, *v_gotofwd, *v_cwd, *v_lasterr;
X
X#define DIR_SHORT 0x01
X#define DIR_FILES 0x02
X#define DIR_DIRS 0x04
X#define DIR_NOCOL 0x08
X
Xextern int has_wild;
Xchar cwd[256];
X
X/*
X Parse the options specified in sw[]
X Setting a bit in global variable options
X for each one found
X*/
X
Xget_opt(sw,count)
Xchar *sw;
Xint *count;
X{
Xregister char *c,*s;
Xunsigned int l,i = 0;
X
Xoptions=0;
Xwhile((++i < ac) && (av[i][0] == '-')) {
X for (c = av[i]+1; *c ; c++) {
X for(l = 0,s = sw;*s && *s != *c; ++s) ++l;
X if (*s) options |= (1 << l);
X }
X }
X*count = i;
X}
X
Xdo_sleep()
X{
Xint i;
X
Xif (ac == 2) for (i=atoi(av[1]); i>0 && !CHECKBREAK(); i-=2) Delay(100L);
Xreturn 0;
X}
X
Xdo_protect()
X{
Xregister long mask=0xf;
Xregister char *s, *p, *flags="DEWRAPSH";
Xregister unsigned int i;
Xfor (s=av[--ac]; *s; s++)
X if (p=index(flags,Toupper(*s))) mask^=(1 << (p-flags));
X else ierror(av[ac],500);
Xfor (i=1; i<ac; i++) if (!SetProtection(av[i],mask)) pError(av[i]);
Xreturn 0;
X}
X
Xdo_filenote()
X{
Xchar *note=av[--ac];
Xregister unsigned int i;
X
Xfor (i=1; i<ac; i++) if (!SetComment(av[i], note)) pError(av[i]);
Xreturn 0;
X}
X
Xdo_cat()
X{
XFILE *fopen(), *fi;
Xregister unsigned int lctr;
Xunsigned int i;
Xchar buf[256];
X
Xget_opt("n",&i);
Xif (i>=ac) {
X if (has_wild) { printf("No files matching\n"); return 20; }
X lctr=0;
X while (gets(buf) && !dobreak()) {
X if (options) printf("%4d ",++lctr);
X puts(buf);
X }
X }
Xfor (; i<ac; i++)
X if (fi = fopen (av[i], "r")) {
X lctr=0;
X while (fgets(buf,256,fi) && !dobreak()) {
X if (options) printf("%4d ",++lctr);
X printf("%s",buf);
X }
X fclose (fi);
X }
X else pError(av[i]);
Xreturn 0;
X}
X
Xdo_info()
X{
XBPTR lock;
Xstruct InfoData *info;
Xunsigned int size, free;
Xchar *p,*s,*state;
Xstruct DirectoryEntry *de_head=NULL, *de;
X
Xinfo=(struct InfoData *)AllocMem((long)sizeof(struct InfoData),MEMF_PUBLIC);
XAddDADevs(&de_head, DLF_DEVICES | DLF_DISKONLY );
XMyprocess->pr_WindowPtr = (APTR)(-1);
Xprintf ("Unit Size Bytes Used Blk/By-Free Full Errs Status Name\n");
Xfor (de=de_head; de; de=de->de_Next) {
X printf("%-5s",de->de_Name);
X if (lock=Lock(de->de_Name,ACCESS_READ)) {
X if (Info(lock, info)) {
X s = get_pwd(lock);
X if (p=index(s,':')) *p = '\0';
X size = ((info->id_NumBlocks + 2)* info->id_BytesPerBlock)/ 1024;
X free = (((info->id_NumBlocks-info->id_NumBlocksUsed))*
X info->id_BytesPerBlock)/ 1024;
X switch(info->id_DiskState) {
X case ID_WRITE_PROTECTED: state="Read Only "; break;
X case ID_VALIDATED: state="Read/Write"; break;
X case ID_VALIDATING: state="Validating"; break;
X }
X printf("%4d%c%6ld%7ld%7ld%4d%c%4ld%%%4ld %s %s\n",
X (size>1024) ? ((size+512) >> 10) : size,
X (size>1024) ? 'M' : 'K',
X info->id_BytesPerBlock,
X info->id_NumBlocksUsed,
X info->id_NumBlocks-info->id_NumBlocksUsed,
X (free>1024) ? ((free+512) >> 10) : free,
X (free>1024) ? 'M' : 'K',
X (info->id_NumBlocksUsed * 100)/info->id_NumBlocks,
X info->id_NumSoftErrors,
X state,
X s);
X }
X else pError (de->de_Name);
X UnLock(lock);
X }
X else puts(" No disk present");
X }
XFreeDAList(&de_head);
XMyprocess->pr_WindowPtr = NULL;
XFreeMem(info,(long)sizeof(struct InfoData));
Xreturn 0;
X}
X
X/* things shared with display_file */
X
Xchar lspec[128];
Xint filecount, col;
Xlong bytes, blocks;
X
X/*
X * the args passed to do_dir will never be expanded
X */
Xdo_dir()
X{
X void display_file();
X int i;
X
X col = filecount = 0;
X bytes = blocks = 0L;
X *lspec = '\0';
X
X get_opt("sfdc",&i);
X
X if (ac == i) {
X ++ac;
X av[i] = "";
X }
X if (!(options & (DIR_FILES | DIR_DIRS))) options|=(DIR_FILES | DIR_DIRS);
X
X for (; i < ac && !CHECKBREAK(); ++i) {
X char **eav;
X int c,eac;
X if (!(eav = expand(av[i], &eac))) continue;
X QuickSort(eav, eac);
X for(c=0;c < eac && !breakcheck();++c) display_file(options,eav[c]);
X free_expand (eav);
X }
X if (col) printf("\n");
X if (filecount > 1) {
X blocks += filecount; /* account for dir blocks */
X printf (" %ld Blocks, %ld Bytes used in %d files\n", blocks, bytes, filecount);
X }
X return 0;
X}
X
Xvoid
Xdisplay_file(options,filestr)
Xint options;
Xchar *filestr;
X{
X long atol();
X int isadir,slen;
X char sc;
X char *c,*s,*fi;
X BPTR lock;
X
X/* if current dir different from lspec then
X look for ':' or '/' if found lock it and get_pwd.
X else then use cwd.
X*/
X for(s = c = filestr; *c; ++c) if (*c == ':' || *c == '/') s = c;
X if (*s == ':') ++s;
X sc = *s;
X *s = '\0';
X c = filestr;
X if (!*c) c = cwd;
X if (strcmp (c, &lspec)) {
X strcpy(lspec, c);
X if (col) printf("\n");
X if (lock=Lock(c,SHARED_LOCK)) {
X printf("Directory of %s\n", get_pwd(lock));
X UnLock(lock);
X }
X col = 0;
X }
X *s = sc;
X if (sc == '/') s++;
X slen = strlen(s);
X fi = s + slen + 1;
X isadir = (fi[12] =='D');
X
X if (!(((options & DIR_FILES) && !isadir) ||
X ((options & DIR_DIRS) && isadir)))
X return;
X if (isadir && !(options & DIR_NOCOL)) printf ("\23333m");
X if (options & DIR_SHORT) {
X if (col==3 && slen>18) { printf("\n"); col = 0; }
X if (slen>18) { printf(" %-37s",s); col+= 2; }
X else { printf(" %-18s",s); col++; }
X if (col > 3) { printf("\n"); col=0; }
X }
X else printf(" %-24s %s",s ,fi);
X if (isadir && !(options & DIR_NOCOL)) printf("\2330m");
X fflush(stdout);
X fi[16] = fi[21] = '\0';
X bytes += atol(fi+10);
X blocks += atol(fi+17);
X filecount++;
X return;
X}
X
Xdo_quit()
X{
Xif (Src_stack) {
X Quit = 1;
X return(do_return());
X }
Xmain_exit(0);
X}
X
Xdo_echo(str)
Xregister char *str;
X{
Xchar nl=1;
X
Xfor (; *str && *str != ' '; ++str);
Xif (*str==' ') ++str;
Xif (av[1] && !strcmp(av[1],"-n")) {
X nl = 0;
X str += 2;
X if (*str==' ') ++str;
X }
Xprintf("%s",str);
Xif (nl) printf("\n");
Xfflush(stdout);
Xreturn 0;
X}
X
X/* gets a line from file, joining two lines if the first ends in '\' */
X
Xchar *myfgets(buf, buflen, file)
Xchar *buf;
XFILE *file;
X{
Xchar *bufptr=buf;
Xint remain=buflen, n, flag;
X
Xdo {
X if (fgets(bufptr, remain, file)==NULL) {
X if (remain != buflen)
X fprintf(stderr,"Source: file ends in '\\'\n");
X return NULL;
X }
X n=strlen(buf);
X bufptr += n;
X if (flag= (*(bufptr-2)=='\\')) bufptr-=2;
X remain -= (n+2);
X } while (flag);
Xreturn buf;
X}
X
Xdo_source(str)
Xchar *str;
X{
Xregister FILE *fi;
Xchar buf[256];
X
Xif (Src_stack == MAXSRC) {
X ierror(NULL,217);
X return -1;
X }
Xif ((fi = fopen (av[1], "r")) == 0) { pError(av[1]); return -1; }
Xset_var(LEVEL_SET, v_passed, next_word(next_word(str)));
X++H_stack;
XSrc_pos[Src_stack] = 0;
XSrc_base[Src_stack] = (long)fi;
X++Src_stack;
Xwhile (myfgets (buf, 256, fi) && !dobreak()) {
X int len = strlen(buf);
X buf[len-1] = '\0';
X Src_pos[Src_stack - 1] += len;
X if (Verbose && !forward_goto) fprintf(stderr,"%s\n",buf);
X exec_command (buf);
X }
X--H_stack;
X--Src_stack;
Xif (forward_goto) ierror(NULL,501);
Xforward_goto = 0;
Xunset_level(LEVEL_LABEL + Src_stack);
Xunset_var(LEVEL_SET, v_gotofwd);
Xunset_var(LEVEL_SET, v_passed);
Xfclose (fi);
Xreturn 0;
X}
X
X/*
X * return ptr to string that contains full cwd spec.
X */
Xchar *get_pwd(flock)
XBPTR flock;
X{
Xstatic char pwdstr[130];
XPathName(flock, pwdstr, 128L);
Xreturn pwdstr;
X}
X
X/*
X * set process cwd name and $_cwd, if str != NULL also print it.
X */
Xdo_pwd(str)
Xchar *str;
X{
Xif (Myprocess->pr_CurrentDir == 0)
X attempt_cd(":"); /* if we just booted 0 = root lock */
Xstrcpy(cwd,get_pwd(Myprocess->pr_CurrentDir,1));
Xif (str) puts(cwd);
Xset_var(LEVEL_SET, v_cwd, cwd);
X/* put the current dir name in our CLI task structure */
XCtoBStr(cwd, Mycli->cli_SetName, 128L);
X}
X
X/*
X * CD
X *
X * CD(str, 0) -do CD operation.
X *
X * standard operation: breakup path by '/'s and process independantly
X * x: -reset cwd base
X * .. -remove last cwd element
X * N -add N or /N to cwd
X */
X
Xdo_cd(str)
Xchar *str;
X{
X char sc, *ptr;
X int err=0;
X
X str = next_word(str);
X if (*str == '\0') {
X puts(cwd);
X return(0);
X }
X str[strlen(str)+1] = '\0'; /* add second \0 on end */
X while (*str) {
X for (ptr = str; *ptr && *ptr != '/' && *ptr != ':'; ++ptr);
X switch (*ptr) {
X case ':':
X sc = ptr[1];
X ptr[1] = '\0';
X err = attempt_cd(str);
X ptr[1] = sc;
X break;
X case '\0':
X case '/':
X *ptr = '\0';
X if (strcmp(str, "..") == 0 || str == ptr)
X str = "/";
X if (*str) err = attempt_cd(str);
X break;
X }
X if (err) break;
X str = ptr + 1;
X }
X do_pwd(NULL); /* set $_cwd */
X return err;
X}
X
Xattempt_cd(str)
Xchar *str;
X{
XBPTR oldlock, filelock;
X
Xif (filelock=Lock(str, ACCESS_READ)) {
X if (isdir(str)) {
X if (oldlock=CurrentDir(filelock)) UnLock(oldlock);
X return (0);
X }
X UnLock(filelock);
X ierror(str, 212);
X }
Xelse ierror(str, 205);
Xreturn -1;
X}
X
Xdo_mkdir()
X{
Xregister unsigned int i;
XBPTR lock;
X
Xfor (i=1; i<ac; ++i) {
X if (exists(av[i])) ierror(av[i],203);
X else if (lock=CreateDir(av[i])) UnLock (lock);
X else pError(av[i]);
X }
Xreturn 0;
X}
X
Xdo_mv()
X{
Xchar *dest, buf[256];
Xint dirflag;
Xregister unsigned int i;
X
Xdirflag=isdir(dest=av[--ac]);
Xif (ac>3 && !dirflag) { ierror(dest, 507); return (-1); }
Xfor (i=1; i<ac; ++i) {
X strcpy(buf, dest);
X if (dirflag) TackOn(buf, BaseName(av[i]));
X if (Rename(av[i], buf)==0)
X { pError(av[i]); return -1; }
X }
Xreturn 0;
X}
X
Xint dirstoo;
X
Xall_args(args, action, dirsflag)
Xchar *args;
Xint (*action)();
X{
Xunsigned int i;
X
Xget_opt(args, &i);
Xdirstoo=dirsflag;
Xfor (; i<ac && !dobreak(); ++i)
X if (isdir(av[i])) {
X if (options & 1) recurse(av[i], action);
X else if (dirstoo) (*action)(av[i]);
X }
X else (*action)(av[i]);
Xreturn 0;
X}
X
Xchar *searchstring;
X
Xsearch_file(s)
Xchar *s;
X{
XFILE *fopen(), *fi;
Xunsigned int lctr, len=strlen(searchstring);
Xint yesno;
Xchar buf[256], lowbuf[256], first;
Xregister char *p, *l, *t;
X
Xif (!(options & 2)) for (t=searchstring; *t=Toupper(*t); t++);
Xfirst=*searchstring;
Xif ((fi=fopen(s, "r"))==NULL) { pError(s); return; }
Xlctr=0;
Xif (!(options & 32)) printf("Examining %s...\n",s);
Xwhile (fgets(buf,256,fi) && !dobreak()) {
X lctr++;
X if (options & 4) yesno=compare_ok(searchstring,buf);
X else {
X yesno=0;
X p=buf;
X if (!(options & 2)) {
X l=lowbuf; /* p is already =buf */
X while (*l++=Toupper(*p++)); /* lowbuf=upper(buf) */
X p=lowbuf;
X }
X while (p=index(p,first))
X if (!strncmp(p++,searchstring,len)) { yesno=1; break; }
X }
X if (yesno ^ ((options & 16)!=0) ) {
X /* default: print line numbers */
X if (!(options & 8)) printf("%4d ",lctr);
X printf("%s",buf);
X }
X }
Xfclose (fi);
X}
X
Xdo_search()
X{
Xsearchstring=av[--ac];
Xall_args("rcwneq", search_file, 0);
Xreturn 0;
X}
X
Xrm_file(file)
Xchar *file;
X{
Xif (has_wild) printf(" %s...",file);
Xif (options & 2) SetProtection(file,0L);
Xif (!DeleteFile(file)) pError (file); else if (has_wild) printf("Deleted\n");
X}
X
Xdo_rm()
X{
Xall_args("rp", rm_file, 1);
Xreturn 0;
X}
X
Xrecurse(name, action)
Xchar *name;
Xint (*action)();
X{
Xregister BPTR lock, cwd;
Xregister FIB *fib=(FIB *)AllocMem((long)sizeof(FIB),MEMF_PUBLIC);
Xchar *namecopy=malloc(256);
X
Xif (name[0] =='\0') return;
Xnamecopy[0]=0;
Xif (lock=Lock(name,ACCESS_READ)) {
X cwd =CurrentDir(lock);
X if (Examine(lock, fib))
X while (ExNext(lock, fib) && !CHECKBREAK()) {
X if (*namecopy) { (*action)(namecopy); namecopy[0]=0; }
X if (fib->fib_DirEntryType>=0) recurse(fib->fib_FileName,action);
X else strcpy(namecopy,fib->fib_FileName);
X }
X if (*namecopy) (*action)(namecopy);
X UnLock(CurrentDir(cwd));
X if (dirstoo) (*action)(name);
X }
Xelse pError(name);
Xfree(namecopy);
XFreeMem(fib, (long)sizeof(FIB));
X}
X
Xdo_history()
X{
Xregister struct HIST *hist;
Xint i = H_tail_base;
Xint len = (av[1]) ? strlen(av[1]) : 0;
X
Xfor (hist = H_tail; hist && !dobreak(); hist = hist->prev)
X if (len == 0 || !strncmp(av[1], hist->line, len))
X printf("%3d %s\n", i++, hist->line);
Xreturn 0;
X}
X
Xdo_mem()
X{
Xlong cfree, ffree;
Xextern long AvailMem();
X
XForbid();
Xcfree = AvailMem (MEMF_CHIP);
Xffree = AvailMem (MEMF_FAST);
XPermit();
Xif (ffree) printf ("FAST memory: %ld\nCHIP memory: %ld\n", ffree, cfree);
Xprintf("Total Free: %ld\n", cfree+ffree);
Xreturn 0;
X}
X
X/* forline i RAM:temp echo line $_linenum: $i */
X
Xdo_forline()
X{
Xchar vname[33], buf[256];
Xregister unsigned short lctr;
XFILE *f;
Xchar *cstr;
Xstatic char *linenumname="_linenum";
X
Xstrcpy(vname,av[1]);
Xf=fopen(av[2],"r");
Xif (f==NULL) pError(av[2]);
Xlctr=0;
X++H_stack;
Xcstr = compile_av (av, 3, ac, ' ');
Xwhile (fgets(buf,256,f) && !dobreak()) {
X buf[strlen(buf)-1]='\0'; /* remove CR */
X lctr++;
X set_var(LEVEL_SET, vname, buf);
X sprintf(buf,"%d",lctr);
X set_var(LEVEL_SET, linenumname, buf);
X exec_command(cstr);
X }
Xfclose(f);
X--H_stack;
Xfree (cstr);
Xunset_var (LEVEL_SET, vname);
Xunset_var (LEVEL_SET, linenumname);
Xreturn 0;
X}
X
X/* fornum i 1 10 echo $i */
X
Xdo_fornum()
X{
Xchar vname[33], buf[16];
Xint n1, n2;
Xchar *cstr;
Xregister int i;
X
Xstrcpy(vname,av[1]);
Xn1=myatoi(av[2],0 ,32767); if (Errno) return 20;
Xn2=myatoi(av[3],n1, 32767); if (Errno) return 20;
X++H_stack;
Xcstr = compile_av (av, 4, ac, ' ');
Xfor (i=n1; i<=n2 && !CHECKBREAK(); i++) {
X sprintf(buf,"%d",i);
X set_var (LEVEL_SET, vname, buf);
X exec_command(cstr);
X }
X--H_stack;
Xfree (cstr);
Xunset_var (LEVEL_SET, vname);
Xreturn 0;
X}
X
X/*
X * foreach var_name ( str str str str... str ) commands
X * spacing is important (unfortunately)
X *
X * ac=0 1 2 3 4 5 6 7
X * foreach i ( a b c ) echo $i
X * foreach i ( *.c ) "echo -n "file ->";echo $i"
X */
X
Xdo_foreach()
X{
Xregister int cstart, cend;
Xregister char *cstr;
Xchar **fav;
Xchar vname[33];
Xint i;
X
Xget_opt("v",&i);
Xstrcpy(vname, av[i++]);
Xif (*av[i] == '(') i++;
Xcstart = i;
Xwhile (i<ac && *av[i] != ')') i++;
Xif (i > ac) { fprintf(stderr,"')' expected\n"); return 20; }
X++H_stack;
Xcend = i;
X
Xfav = (char **)malloc(sizeof(char *) * (ac));
Xcstr = compile_av (av, cend + 1, ac, ' ');
X
Xfor (i = cstart; i < cend; ++i) fav[i] = av[i];
X
Xfor (i = cstart; i<cend && !CHECKBREAK(); ++i) {
X set_var (LEVEL_SET, vname, fav[i]);
X if (options & 1) printf("foreach: %s\n", fav[i]);
X exec_command(cstr);
X }
X--H_stack;
Xfree (fav);
Xfree (cstr);
Xunset_var (LEVEL_SET, vname);
Xreturn 0;
X}
X
Xdo_forever(str)
Xchar *str;
X{
Xint rcode = 0;
Xchar *ptr = next_word(str);
X
X++H_stack;
Xfor (;;) {
X if (CHECKBREAK()) { rcode = 20; break; }
X if (exec_command (ptr) < 0) {
X str = get_var(LEVEL_SET, v_lasterr);
X rcode = (str) ? atoi(str) : 20;
X break;
X }
X }
X--H_stack;
Xreturn rcode;
X}
X
Xdo_exec(str)
Xchar *str;
X{
Xreturn exec_command(next_word(str));
X}
X
Xextern struct Window *w;
Xextern struct IntuitionBase *IntuitionBase;
X
Xdo_window()
X{
Xlong x, y, maxwidth, maxheight, arg[5];
Xunsigned int i;
Xstruct Screen *screen;
Xstruct Window *window;
X
Xget_opt("slfbaq", &i);
Xif (options & 1)
X SizeWindow(w, (long)(w->MinWidth-w->Width), (long)(w->MinHeight-w->Height));
Xif (options & 2) {
X x=-w->LeftEdge;
X y=-w->TopEdge;
X MoveWindow(w,x,y);
X x=IntuitionBase->ActiveScreen->Width -w->Width;
X y=IntuitionBase->ActiveScreen->Height-w->Height;
X SizeWindow(w,x,y);
X }
Xif (options & 4) WindowToFront(w);
Xif (options & 8) WindowToBack(w);
Xif (options & 16) ActivateWindow(w);
Xif(ac >= 5) {
X for(i=1; i<5; i++) {
X arg[i] = myatoi(av[i],0,1023);
X if (Errno) return 20;
X }
X maxwidth = w->WScreen->Width;
X maxheight= w->WScreen->Height;
X if (arg[3] > maxwidth - arg[1] || arg[4] > maxheight- arg[2]) {
X ierror(NULL, 500);
X return 20;
X }
X x = -w->LeftEdge;
X y = -w->TopEdge;
X MoveWindow(w, x, y);
X x = arg[3] - w->Width;
X y = arg[4] - w->Height;
X SizeWindow(w, x, y);
X x = arg[1];
X y = arg[2];
X MoveWindow(w, x, y);
X }
Xif(options & 32) {
X for (screen=IntuitionBase->FirstScreen; screen; screen=screen->NextScreen) {
X printf("\nScreen \"%s\" (%d,%d,%dx%d):\n",
X screen->Title,
X screen->LeftEdge,
X screen->TopEdge,
X screen->Width,
X screen->Height
X );
X for (window=screen->FirstWindow; window; window=window->NextWindow) {
X printf("\tWindow\t\"%s\" (%d,%d,%dx%d)\n",
X window->Title,
X window->LeftEdge,
X window->TopEdge,
X window->Width,
X window->Height
X );
X }
X }
X return 0;
X }
XDelay(25L); /* pause 1/2 sec. before trying to print */
Xprintf("\014");
Xreturn 0;
X}
X
Xsetsystemtime(ds)
Xstruct DateStamp *ds;
X{
Xstruct timerequest tr;
Xlong secs= ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND;
X
Xif (OpenDevice(TIMERNAME, UNIT_VBLANK, &tr, 0L)) {
X fprintf(stderr,"Clock error: can't open timer device\n");
X return;
X }
Xtr.tr_node.io_Message.mn_Node.ln_Type = NT_MESSAGE;
Xtr.tr_node.io_Message.mn_Node.ln_Pri = 0L;
Xtr.tr_node.io_Message.mn_Node.ln_Name = NULL;
Xtr.tr_node.io_Message.mn_ReplyPort = NULL;
Xtr.tr_node.io_Command = TR_SETSYSTIME;
Xtr.tr_time.tv_secs = secs;
Xtr.tr_time.tv_micro = 0L;
Xif (DoIO (&tr)) fprintf(stderr,"Clock error: can't talk to timer device\n");
XCloseDevice (&tr);
X}
X
Xchar tday[10];
X
Xchar *dates(dss)
Xstruct DateStamp *dss;
X{
Xstatic char timestr[40];
Xchar tdate[10], ttime[10];
Xstruct DateTime dt;
Xstruct DateStamp *myds=&(dt.dat_Stamp);
X
Xdt.dat_Format=FORMAT_DOS;
Xdt.dat_StrDay=tday;
Xdt.dat_StrDate=tdate;
Xdt.dat_StrTime=ttime;
Xdt.dat_Flags=NULL;
Xmyds->ds_Days=dss->ds_Days;
Xmyds->ds_Minute=dss->ds_Minute;
Xmyds->ds_Tick=dss->ds_Tick;
XStamptoStr(&dt);
Xsprintf(timestr,"%s %s\n",tdate,ttime);
Xtimestr[18]='\n';
Xtimestr[19]='\0'; /* protection against bad timestamped files */
Xreturn timestr;
X}
X
Xdate()
X{
Xstruct DateStamp dss;
Xregister unsigned short i;
Xstruct DateTime dt;
X
Xdt.dat_Format=FORMAT_DOS;
Xif (ac==1) {
X DateStamp(&dss);
X printf("%s %s",tday,dates(&dss));
X }
Xelse {
X DateStamp(& (dt.dat_Stamp));
X for (i=1; i<ac; i++) {
X dt.dat_StrDate=NULL;
X dt.dat_StrTime=NULL;
X dt.dat_Flags=DTF_FUTURE;
X if (index(av[i],':')) dt.dat_StrTime=av[i];
X else dt.dat_StrDate=av[i];
X if (StrtoStamp(&dt)) ierror(av[i],500);
X }
X setsystemtime( & (dt.dat_Stamp) );
X }
Xreturn 0;
X}
SHAR_EOF
echo "extracting comm2.c"
sed 's/^X//' << \SHAR_EOF > comm2.c
X/*
X * COMM2.C
X *
X * (c)1986 Matthew Dillon 9 October 1986
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X *
X * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89
X *
X */
X
Xextern char *v_gotofwd;
X
X/* Casting conveniences */
X#define BPTR_TO_C(strtag, var) ((struct strtag *)(BADDR( (ULONG) var)))
X#define PROC(task) ((struct Process *)task)
X#define CLI(proc) (BPTR_TO_C(CommandLineInterface, proc->pr_CLI))
X
X/* Externs */
Xextern int has_wild; /* flag set if any arg has a ? or * */
X
X/* globals */
Xint cp_update;
Xint cp_date;
X
Xdo_abortline()
X{
XExec_abortline = 1;
Xreturn 0;
X}
X
Xdo_return()
X{
Xregister int retcode=(ac<2 ? 0 : atoi(av[1]));
X Exec_abortline = 1;
X if (Src_stack) {
X FILE *ptr = (FILE *)Src_base[Src_stack - 1];
X ptr->_bp = ptr->_bend;
X ptr->_flags |= _EOF;
X/* fseek (Src_base[Src_stack - 1], 0L, 2); */
X return retcode;
X } else main_exit(retcode);
X}
X
X/*
X * STRHEAD
X *
X * place a string into a variable removing everything after and including
X * the 'break' character
X *
X * strhead varname breakchar string
X *
X */
X
Xdo_strhead()
X{
Xchar *s;
Xif (s=index(av[3],*av[2])) *s='\0';
Xset_var (LEVEL_SET, av[1], av[3]);
Xreturn 0;
X}
X
Xdo_strtail()
X{
Xchar *s;
Xif (s=index(av[3],*av[2])) s++; else s=av[3];
Xset_var (LEVEL_SET, av[1], s);
Xreturn 0;
X}
X
Xlong dptrtosecs(d)
Xstruct DPTR *d;
X{
Xregister struct DateStamp *ds=(&d->fib->fib_Date);
Xreturn ds->ds_Days*86400 + ds->ds_Minute*60 + ds->ds_Tick/TICKS_PER_SECOND;
X}
X
Xlong timeof(s)
Xchar *s;
X{
Xstruct DPTR *d;
Xint dummy;
Xlong n;
X
Xif ( (d=dopen(s,&dummy))==NULL ) return 0L;
Xn=dptrtosecs(d);
Xdclose(d);
Xreturn n;
X}
X
X/*
X * if -f file (exists) or:
X *
X * if A < B <, >, =, <=, >=, <>, where A and B are either:
X * nothing
X * a string
X * a value (begins w/ number)
X */
X
Xdo_if(garbage, com)
Xchar *garbage;
X{
Xint result;
Xint i;
X
Xswitch (com) {
X case 0:
X if (If_stack && If_base[If_stack - 1]) If_base[If_stack++] = 1;
X else {
X get_opt("rftmdn",&i);
X result=evalif(i);
X If_base[If_stack++]=(options & 32 ? result : !result);
X }
X break;
X case 1:
X if (If_stack > 1 && If_base[If_stack - 2]) break;
X if (If_stack) If_base[If_stack - 1] ^= 1;
X break;
X case 2:
X if (If_stack) --If_stack;
X break;
X }
Xdisable = (If_stack) ? If_base[If_stack - 1] : 0;
Xif (If_stack >= MAXIF) {
X fprintf(stderr,"If's too deep\n");
X disable = If_stack = 0;
X return -1;
X }
Xif (forward_goto) disable = If_base[If_stack - 1] = 0;
Xreturn 0;
X}
X
Xevalif(i)
Xregister unsigned int i;
X{
Xchar c;
Xlong num, t0;
Xlong AvailMem();
X
Xswitch(options & ~32) {
X case 0:
X if (ac-i != 3) return (ac>i && *av[i]);
X Errno=0;
X num=Atol(av[i])-Atol(av[i+2]);
X if (Errno) num=strcmp(av[i],av[i+2]);
X if (num < 0) c='<';
X else if (num > 0) c='>';
X else if (num == 0) c='=';
X return index(av[i+1], c) != NULL;
X case 1:
X return do_rpn(NULL,i);
X case 2:
X return exists(av[i]);
X case 4:
X t0=timeof(av[i++]);
X for ( ; i<ac ; i++)
X if (t0<=timeof(av[i])) return 1;
X return 0;
X case 8:
X return (AvailMem( (long)MEMF_FAST )!=0);
X case 16:
X return (isdir(av[i])!=0);
X default:
X ierror(NULL,500);
X return 0;
X }
X}
X
Xdo_label()
X{
X char aseek[32];
X
X if (Src_stack == 0) {
X ierror (NULL, 502);
X return (-1);
X }
X
X sprintf (aseek, "%ld %d", Src_pos[Src_stack-1], If_stack);
X set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek);
X if (!strcmp(av[1],get_var(LEVEL_SET,v_gotofwd)))
X forward_goto = 0;
X return 0;
X}
X
Xdo_goto()
X{
X int new;
X long pos;
X char *lab;
X
X if (Src_stack == 0) {
X ierror (NULL, 502);
X } else {
X lab = get_var (LEVEL_LABEL + Src_stack - 1, av[1]);
X if (lab == NULL) {
X forward_goto = 1;
X set_var (LEVEL_SET, v_gotofwd, av[1]);
X return(0);
X } else {
X pos = atoi(lab);
X fseek (Src_base[Src_stack - 1], pos, 0);
X Src_pos[Src_stack - 1] = pos;
X new = atoi(next_word(lab));
X for (; If_stack < new; ++If_stack)
X If_base[If_stack] = 0;
X If_stack = new;
X }
X }
X Exec_abortline = 1;
X return (0); /* Don't execute rest of this line */
X}
X
X
Xdo_inc(garbage, com)
Xchar *garbage;
X{
Xchar *var, num[32];
X
Xif (ac>2) com *= atoi(av[2]);
Xif (var = get_var (LEVEL_SET, av[1])) {
X sprintf (num, "%d", atoi(var)+com);
X set_var (LEVEL_SET, av[1], num);
X }
Xreturn 0;
X}
X
Xdo_input()
X{
Xchar in[256], *p,*s;
Xunsigned int i;
X
Xfor (i=1; i < ac; ++i)
X if (gets(in)) {
X for(p = in; *p; p = s) {
X s = next_word(p);
X if (*s) *(s-1) = 0xA0;
X }
X set_var (LEVEL_SET, av[i], in);
X }
Xreturn 0;
X}
X
Xdo_ver()
X{
Xputs("Shell V3.03A\n\
X)1986 Matthew Dillon\n\
XManx (M) versions by Steve Drew\n\
XARP (A) versions by Carlo Borreo & Cesare Dieni\n");
Xreturn 0;
X}
X
Xdo_ps()
X{
X/* this code fragment based on ps.c command by Dewi Williams */
X
Xregister int count; /* loop variable */
Xstruct Task *task; /* EXEC descriptor */
Xchar strbuf[64+1]; /* scratch for btocstr() */
Xchar cmd[40+1]; /* holds cmd name */
Xlong ncli;
X
Xprintf("Proc Command Name CLI Type Pri. Address Directory\n");
XForbid();
X
Xncli=(long)FindCLI(0L);
Xfor (count = 1; count <= ncli ; count++)
X /* or just assume 20?*/
X if (task = (struct Task *)FindCLI((long)count)) {
X if (task==NULL) continue;
X /* Sanity check just in case */
X if (PROC(task)->pr_TaskNum == 0 || PROC(task)->pr_CLI == 0) continue;
X /* or complain? */
X BtoCStr(cmd, CLI(PROC(task))->cli_CommandName, 40L);
X BtoCStr(strbuf,CLI(PROC(task))->cli_SetName , 64L);
X printf("%2d %-20.20s %-11.11s %3d %8lx %s\n",
X count,
X cmd,
X task->tc_Node.ln_Name,
X task->tc_Node.ln_Pri,
X task,
X strbuf);
X }
XPermit();
Xreturn 0;
X}
X
X/*
X * CP [-d] [-u] file file
X * CP [-d] [-u] file file file... destdir
X * CP [-r][-u][-d] dir dir dir... destdir
X */
X
Xchar *errstr; /* let's be alittle more informative */
X
Xdo_copy()
X{
Xregister int recur, ierr;
Xregister char *destname;
Xregister char destisdir;
Xregister FIB *fib;
Xint i;
X
Xerrstr = "";
Xierr = 0;
X
Xfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
X
Xget_opt("rud",&i);
Xrecur = (options & 0x01);
Xcp_update = (options & 0x02);
Xcp_date = (!(options & 0x04)); /* the default is keep orignal file date */
X
Xdestname = av[ac - 1];
X
Xif (ac < i + 2) {
X ierr = 500;
X goto done;
X }
Xdestisdir = isdir(destname);
Xif (ac > i + 2 && !destisdir) {
X ierr = 507;
X goto done;
X }
X
X/*
X * copy set: reduce to:
X * file to file file to file
X * dir to file (NOT ALLOWED)
X * file to dir dir to dir
X * dir to dir dir to dir
X *
X */
X
Xfor (; i<ac-1 && !dobreak(); ++i) {
X short srcisdir = isdir(av[i]);
X if (srcisdir && has_wild && (ac >2)) /* hack to stop dir's from */
X continue; /* getting copied if specified */
X /* from wild expansion */
X if (srcisdir) {
X BPTR srcdir, destdir;
X if (!destisdir) {
X if (exists(destname)) {
X ierr = 507; /* disallow dir to file */
X goto done;
X }
X if (destdir = CreateDir(destname)) UnLock(destdir);
X destisdir = 1;
X }
X if (!(destdir = Lock(destname, ACCESS_READ))) {
X ierr = 205;
X errstr = destname;
X goto done;
X }
X if (!(srcdir = Lock(av[i], ACCESS_READ))) {
X ierr = 205;
X errstr = av[i];
X UnLock(destdir);
X goto done;
X }
X ierr = copydir(srcdir, destdir, recur);
X UnLock(srcdir);
X UnLock(destdir);
X if (ierr) break;
X }
X else { /* FILE to DIR, FILE to FILE */
X BPTR destdir, srcdir, tmp;
X char *destfilename;
X
X srcdir = (BPTR)(Myprocess->pr_CurrentDir);
X
X if ((tmp = Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)) {
X if (tmp) UnLock(tmp);
X ierr = 205;
X errstr = av[i];
X goto done;
X }
X UnLock(tmp);
X if (destisdir) {
X destdir = Lock(destname, ACCESS_READ);
X destfilename = fib->fib_FileName;
X }
X else {
X destdir = srcdir;
X destfilename = destname;
X }
X printf(" %s..",av[i]);
X fflush(stdout);
X ierr = copyfile(av[i], srcdir, destfilename, destdir);
X if (destisdir) UnLock(destdir);
X if (ierr) break;
X }
X }
X
Xdone:
X
XFreeMem(fib, (long)sizeof(FIB));
Xif (ierr) {
X ierror(errstr, ierr);
X return(20);
X }
Xreturn 0;
X}
X
X
Xcopydir(srcdir, destdir, recur)
Xregister BPTR srcdir, destdir;
X{
X BPTR cwd;
X register FIB *srcfib;
X register BPTR destlock, srclock;
X int ierr;
X static int level;
X
X level++;
X ierr = 0;
X srcfib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
X if (Examine(srcdir, srcfib)) {
X while (ExNext(srcdir, srcfib)) {
X if (CHECKBREAK())
X break;
X if (srcfib->fib_DirEntryType < 0) {
X printf("%*s%s..",(level-1) * 6," ",srcfib->fib_FileName);
X fflush(stdout);
X ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir);
X if (ierr)
X break;
X } else {
X if (recur) {
X cwd = CurrentDir(srcdir);
X if (srclock = Lock(srcfib->fib_FileName, ACCESS_READ)) {
X CurrentDir(destdir);
X if (!(destlock = Lock(srcfib->fib_FileName))) {
X destlock = CreateDir(srcfib->fib_FileName);
X printf("%*s%s (Dir)....[Created]\n",(level-1) * 6,
X " ",srcfib->fib_FileName);
X
X /* UnLock and re Lock if newly created
X for file_date() to work properly
X */
X if (destlock) UnLock(destlock);
X destlock = Lock(srcfib->fib_FileName);
X }
X else
X printf("%*s%s (Dir)\n",(level-1) * 6," ",srcfib->fib_FileName);
X if (destlock) {
X ierr = copydir(srclock, destlock, recur);
X UnLock(destlock);
X } else {
X ierr = (int)((long)IoErr());
X }
X UnLock(srclock);
X } else {
X ierr = (int)((long)IoErr());
X }
X CurrentDir(cwd);
X if (ierr)
X break;
X }
X }
X }
X } else {
X ierr = (int)((long)IoErr());
X }
X --level;
X FreeMem(srcfib, (long)sizeof(FIB));
X return(ierr);
X}
X
X
Xcopyfile(srcname, srcdir, destname, destdir)
Xchar *srcname, *destname;
XBPTR srcdir, destdir;
X{
XBPTR cwd;
XBPTR f1, f2;
Xlong i;
Xint stat,ierr;
Xchar *buf;
Xstruct DPTR *dp, *dps = NULL;
X
Xif ((buf = (char *)AllocMem(8192L, MEMF_PUBLIC|MEMF_CLEAR))==NULL)
X { ierr = 103; goto fail; }
Xierr = 0;
Xcwd = CurrentDir(srcdir);
Xif ((f1=Open(srcname, MODE_OLDFILE))==NULL)
X { errstr = srcname; ierr = 205; goto fail; }
Xdps = dopen(srcname,&stat);
XCurrentDir(destdir);
Xif (cp_update)
X {
X dp=dopen(destname, &stat);
X if ( dptrtosecs(dp) >= dptrtosecs(dps) &&
X !strcmp(dps->fib->fib_FileName, dp->fib->fib_FileName))
X { dclose(dp); Close(f1); printf("..not newer\n"); goto fail; }
X dclose(dp);
X }
Xif ((f2=Open(destname, MODE_NEWFILE))==NULL)
X { Close(f1); ierr = (int)((long)IoErr()); errstr=destname; goto fail; }
Xwhile (i = Read(f1, buf, 8192L))
X if (Write(f2, buf, i) != i) { ierr = (int)((long)IoErr()); break; }
XClose(f2);
XClose(f1);
Xif (!ierr)
X {
X if (cp_date) file_date(&dps->fib->fib_Date, destname);
X printf("..copied\n");
X }
Xelse DeleteFile(destname);
Xfail:
X dclose(dps);
X if (buf) FreeMem(buf, 8192L);
X CurrentDir(cwd);
X return(ierr);
X}
X
Xdo_touch()
X{
Xstruct DateStamp ds;
Xregister unsigned int i;
XDateStamp(&ds);
Xfor (i=1; i<ac; i++) if (file_date(&ds, av[i])) ierror(av[i],500);
Xreturn 0;
X}
X
Xfile_date(date,name)
Xstruct DateStamp *date;
Xchar *name;
X{
Xlong packargs[7];
XUBYTE *ptr;
Xstruct MsgPort *task;
XBPTR dirlock;
Xstruct DPTR *tmp;
Xint stat;
X
Xif (!(task = (struct MsgPort *)DeviceProc(name))) return(1);
Xif (tmp = dopen(name, &stat)) {
X dirlock = ParentDir(tmp->lock);
X ptr=AllocMem(65L,MEMF_PUBLIC);
X CtoBStr(tmp->fib->fib_FileName,(ULONG)ptr >> 2L,64L);
X dclose(tmp);
X packargs[1]=dirlock;
X packargs[2]=(ULONG)ptr >> 2L;
X packargs[3]=(long)date;
X SendPacket(ACTION_SET_DATE,packargs,task);
X UnLock(dirlock);
X FreeMem(ptr,65L);
X }
Xreturn 0;
X}
X
Xdo_addbuffers()
X{
Xlong packargs[7];
Xlong n;
Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
X
Xif (!task) { ierror(av[1],510); return 20; }
Xn=myatoi(av[2],1,32767); if (Errno) return 20;
Xpackargs[0]=n;
XSendPacket(ACTION_MORE_CACHE,packargs,task);
Xreturn 0;
X}
X
Xdo_relabel()
X{
Xlong packargs[7];
XUBYTE *ptr;
Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
X
Xif (!task) { ierror(av[1],510); return 20; }
Xptr=AllocMem(65L,MEMF_PUBLIC);
XCtoBStr(av[2],(ULONG)ptr >> 2L,64L);
Xpackargs[0]=(ULONG)ptr >> 2L;
XSendPacket(ACTION_RENAME_DISK,packargs,task);
XFreeMem(ptr,65L);
Xchangedisk(task);
Xreturn 0;
X}
X
Xdo_diskchange()
X{
Xstruct MsgPort *task=(struct MsgPort *)DeviceProc(av[1]);
X
Xif (!task) { ierror(av[1],510); return 20; }
Xchangedisk(task);
Xreturn 0;
X}
X
Xchangedisk(task)
Xstruct MsgPort *task;
X{
Xlong packargs[7];
X
Xpackargs[0]=1L;
XSendPacket(ACTION_INHIBIT,packargs,task);
Xpackargs[0]=0L;
XSendPacket(ACTION_INHIBIT,packargs,task);
X}
SHAR_EOF
echo "extracting comm3.c"
sed 's/^X//' << \SHAR_EOF > comm3.c
X/*
X * COMM3.C
X *
X * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89
X *
X */
X
Xdo_assign() {
Xswitch(ac) {
X case 1: assignlist();
X break;
X case 2: doassign(av[1], NULL);
X break;
X case 3: doassign(av[1], av[2]);
X break;
X default: ierror(NULL, 500);
X break;
X }
Xreturn 0;
X}
X
Xchar *assign_errors[4]={
X "",
X "Name %s is not valid\n",
X "Weird error\n",
X "Can't cancel %s\n"
X };
X
Xdoassign(log, phy)
Xchar *log, *phy;
X{
Xint last=strlen(log) - 1;
X
Xif (log[last] != ':') fprintf(stderr, "Bad name %s\n", log);
Xelse {
X log[last] = 0;
X fprintf(stderr,assign_errors[Assign(log, phy)],log);
X }
X}
X
Xassignlist()
X{
Xstruct DirectoryEntry *de_head=NULL, *de;
Xchar buf[256];
XBPTR lock;
Xint ctr=0;
X
XAddDADevs(&de_head, DLF_DEVICES | DLF_VOLUMES | DLF_DIRS);
Xprintf("Devices:\n");
Xfor (de=de_head; de && de->de_Type==DLX_DEVICE; de=de->de_Next) {
X printf("%-8s",de->de_Name);
X if (ctr++ == 5) { ctr=0; printf("\n"); }
X }
Xprintf("\n\nVolumes:\n");
Xfor ( ;
X de && (de->de_Type==DLX_VOLUME || de->de_Type==DLX_UNMOUNTED);
X de=de->de_Next
X )
X printf( "%-16s %s\n",
X de->de_Name,
X de->de_Type == DLX_VOLUME ? "[Mounted]" : ""
X );
Xprintf("\nDirectories:\n");
Xfor (; de && de->de_Type==DLX_ASSIGN; de=de->de_Next) {
X if (lock=Lock(de->de_Name, ACCESS_READ)) {
X PathName(lock, buf, 256L);
X UnLock(lock);
X }
X else
X strcpy(buf,"Unexisting lock");
X printf("%-20s%s\n",de->de_Name,buf);
X }
XFreeDAList(&de_head);
X}
X
Xdo_join()
X{
XBPTR sou, dest;
Xchar *buffer;
Xunsigned int i;
Xlong n;
Xchar *namedest=av[--ac];
X
Xget_opt("r", &i);
Xif (options==0 && exists(namedest)) { ierror(namedest,203); return 20; }
Xif ( (buffer=malloc(8192)) == NULL ) { ierror(NULL,103); return 20; }
Xif ( (dest=Open(namedest, MODE_NEWFILE)) == NULL )
X { pError(namedest); goto fail1; }
Xfor (i=1; i<ac; i++) {
X if ( (sou=Open(av[i], MODE_OLDFILE)) == NULL ) pError(av[i]);
X else
X while( (n=Read(sou, buffer, 8192L)) > 0 )
X if (Write(dest, buffer, n) != n)
X { pError(namedest); Close(sou); goto fail2; }
X Close(sou);
X }
Xfail2:
X Close(dest);
Xfail1:
X free(buffer);
X return 0;
X}
X
X#define BUFDIM 512L
X#define MAXSTR 256
X
Xint minstr;
X
Xstrings_in_file(s)
Xchar *s;
X{
Xchar c;
Xchar readbuf[BUFDIM+1], strbuf[MAXSTR+1];
Xregister unsigned int i, strctr=0;
XBPTR fh;
Xint out, n;
X
Xif ( fh=Open(s, MODE_OLDFILE) ) {
X fprintf(stderr, "Strings in %s (len>=%d):\n",s,minstr);
X while ( (n=(int)Read(fh, readbuf, BUFDIM)) > 0 && !CHECKBREAK() )
X for (i=0; i<n; i++) {
X c=readbuf[i];
X if (c<0x20 || c>0x7f) {
X out=(strctr>=minstr);
X if (!out) strctr=0;
X }
X else {
X strbuf[strctr++]=c;
X out=(strctr>=BUFDIM);
X }
X if (out) {
X strbuf[strctr]='\0';
X puts(strbuf);
X strctr=0;
X }
X }
X Close(fh);
X }
Xelse pError(s);
X}
X
Xdo_strings()
X{
Xminstr=myatoi(av[--ac],1,255);
Xall_args("r", strings_in_file, 0);
Xreturn 0;
X}
X
XBPTR myfile[MAXMYFILES];
X
Xdo_open()
X{
Xlong mode;
Xunsigned int n;
X
Xswitch (av[2][0]) {
X case 'r': mode=MODE_OLDFILE; break;
X case 'w': mode=MODE_NEWFILE; break;
X default : ierror(NULL,500); return;
X }
XErrno=0;
Xn=(unsigned int)myatoi(av[3],0,MAXMYFILES); if (Errno) return 20;
Xmyfile[n]=Open(av[1],mode);
Xreturn (myfile[n]==NULL);
X}
X
Xdo_close()
X{
Xregister unsigned int i;
Xint n;
X
Xfor (i=1; i<ac; i++) {
X Errno=0;
X n=myatoi(av[i],0,MAXMYFILES); if (Errno) return 20;
X myclose(n);
X }
Xreturn 0;
X}
X
Xmyclose(n)
X{
Xif (myfile[n]) { Close(myfile[n]); myfile[n]=NULL; }
X}
X
Xdo_fileslist()
X{
Xregister unsigned short i;
Xint flag=0;
X
Xprintf("Open files:");
Xfor (i=0; i<MAXMYFILES; i++)
X if (myfile[i]) { printf(" %d",i); flag=1; }
Xif (!flag) printf(" None!");
Xprintf("\n");
Xreturn 0;
X}
X
XBPTR extOpen(name,mode)
Xchar *name;
Xlong mode;
X{
Xif (name[0]=='.') return myfile[atoi(name+1)];
Xreturn Open(name,mode);
X}
X
XextClose(fh)
XBPTR fh;
X{
Xregister unsigned short i;
X
Xfor (i=0; i<MAXMYFILES; i++)
X if (myfile[i]==fh) return;
XClose(fh);
X}
X
Xdo_resident(avline)
Xchar *avline;
X{
Xunsigned int i;
XBPTR seg;
Xstruct ResidentPrgNode *p;
X
Xget_opt("ar", &i);
Xswitch (options) {
X case 0:
X ObtainSemaphore (& (ArpBase->ResPrgProtection) );
X if (p=ArpBase->ResidentPrgList) {
X printf("Name Users\n");
X for (; p; p=p->rpn_Next)
X printf("%-16s %-3ld\n",p->rpn_Name,p->rpn_Usage);
X }
X else printf("No resident program(s)\n");
X ReleaseSemaphore(& (ArpBase->ResPrgProtection) );
X break;
X case 1:
X for (; i<ac; i++)
X if ( (seg=(BPTR)LoadPrg(av[i])) && AddResidentPrg(seg,av[i]) )
X printf("OK! %s is now resident\n", BaseName(av[i]));
X else pError(av[i]);
X break;
X case 2:
X for (; i<ac; i++)
X if (RemResidentPrg(av[i])) ierror(av[i],202);
X else printf("Removed %s\n",av[i]);
X break;
X default:
X ierror(NULL,500);
X break;
X }
Xreturn 0;
X}
X
Xstruct ProcessControlBlock pcb={
X 4000, /* pcb_StackSize */
X 0, /* pcb_Pri */
X };
X/* remaining field are NULL */
X
Xdo_truerun(avline, backflag)
Xchar *avline;
X{
Xchar name[200];
Xchar *FindIt();
X
Xif (backflag) {
X pcb.pcb_Control=NULL;
X pcb.pcb_Input=pcb.p_Output=Open("NIL:",MODE_OLDFILE);
X }
Xelse {
X pcb.pcb_Control=NULL;
X pcb.pcb_Input=pcb.p_Output =NULL;
X }
Xif (FindIt(av[1], "", name))
X ASyncRun(name,next_word(next_word(avline)),&pcb);
Xelse
X ierror(av[1],205);
Xreturn 0;
X}
X
Xint exists(name)
Xchar *name;
X{
XBPTR lock;
X
Xif (lock=Lock(name,ACCESS_READ)) {
X UnLock(lock);
X return 1;
X }
Xreturn 0;
X}
X
Xdo_aset()
X{
XSetenv(av[1],av[2]);
Xreturn 0;
X}
X
X#define HTYPELINE 16L
X
Xhtype_a_file(s)
Xchar *s;
X{
XBPTR fh;
Xlong n, filesize=0;
Xchar buf[HTYPELINE+1];
Xregister unsigned int i;
X
Xif ( (fh=Open(s,MODE_OLDFILE))==NULL ) { pError(s); return 20; }
Xwhile ( (n=Read(fh,buf,HTYPELINE))>0 && !dobreak()) {
X printf("%06lx: ",filesize);
X filesize+=n;
X for (i=0; i<n; i++) {
X printf( (i&3) ? "%02x" : " %02x",(int)(unsigned char)buf[i]);
X if (buf[i]<=0x20) buf[i]='.';
X }
X for ( ; i<HTYPELINE; i++) {
X printf( (i&3) ? " " : " ");
X buf[i]=' ';
X }
X buf[i]=0;
X printf(" %s\n",buf);
X }
XClose(fh);
Xreturn 0;
X}
X
Xdo_htype()
X{
Xall_args("", htype_a_file, 0);
Xreturn 0;
X}
X
Xdo_stack()
X{
Xlong n;
X
Xif (ac>1) {
X Errno=0;
X n=Atol(av[1]);
X if (!Errno) Mycli->cli_DefaultStack=(long)(n >> 2L);
X }
Xelse printf("current stack size is %ld bytes\n",
X (long)Mycli->cli_DefaultStack << 2L);
Xreturn 0;
X}
X
Xdo_fault()
X{
Xstruct PERROR *p;
Xregister unsigned int i;
Xint n;
X
Xfor (i=1; i<ac; i++) {
X n=myatoi(av[i],0,32767);
X if (!Errno) {
X for (p=Perror; p->errnum && p->errnum!=n; p++);
X if (p->errnum)
X printf("Fault %d: %s\n",n,p->errstr);
X else
X printf("Fault %d not recognized\n",n);
X }
X }
Xreturn 0;
X}
X
Xstruct rpncommand {
X char *str;
X int parsin, parsout;
X };
X
Xstruct rpncommand rpn[]={
X "+", 2, 1,
X "-", 2, 1,
X "*", 2, 1,
X "/", 2, 1,
X "%", 2, 1,
X "&", 2, 1,
X "|", 2, 1,
X "~", 1, 1,
X ">", 2, 1,
X "<", 2, 1,
X "==", 2, 1,
X "!", 1, 1,
X "DUP", 1, 2,
X "DROP", 1, 0,
X "SWAP", 2, 2,
X "HELP", 0, 0,
X NULL, 0, 1, /* this looks for a number */
X};
X
Xdo_rpn(garbage,ifflag) /* ifflag!=0 if called from if */
Xchar *garbage;
X{
Xregister long n0, n1;
Xlong t;
Xunsigned int i, j;
Xint sp=0;
Xlong stack[100];
Xstruct rpncommand *temp;
X
Xi=1;
Xif (ifflag) get_opt("rn",&i);
Xfor (; i<ac; i++) {
X for (j=0; rpn[j].str && Strcmp(rpn[j].str,av[i]); j++) ;
X n0=stack[sp-1];
X n1=stack[sp-2];
X sp -= (rpn[j].parsin);
X if (sp<0) { fprintf(stderr, "RPN: Empty stack\n"); return 1; }
X switch (j) {
X case 0: n0 += n1; break;
X case 1: n0 = n1-n0; break;
X case 2: n0 *= n1; break;
X case 3: n0 = n1/n0; break;
X case 4: n0 = n1%n0; break;
X case 5: n0 &= n1; break;
X case 6: n0 |= n1; break;
X case 7: n0 = ~n0; break;
X case 8: n0 = (n1 > n0); break;
X case 9: n0 = (n1 < n0); break;
X case 10: n0 = (n0 == n1); break;
X case 11: n0 = !n0; break;
X case 12: n1=n0; break;
X case 13: t=n0; n0=n1; n1=t; break;
X case 14: break;
X case 15: printf("In Commands Out\n");
X for (temp=rpn; temp->str; temp++)
X printf(" %d %-10s%d\n",
X temp->parsin,temp->str,temp->parsout);
X break;
X default: Errno=0;
X n0=Atol(av[i]);
X if (Errno) {
X fprintf(stderr, "Bad RPN cmd: %s\n",av[i]);
X return 20;
X }
X break;
X }
X stack[sp]=n0;
X stack[sp+1]=n1;
X sp += rpn[j].parsout;
X }
Xif (ifflag) return (int)(stack[sp-1]); /* called from if: return top value */
Xfor (i=sp-1;(int)i>=0;i--) printf("%ld\n", stack[i]); /* else print stack */
Xreturn 0;
X}
X
Xdo_path()
X{
Xunion { long *lp; long ll; } l;
Xchar buf[256];
X
Xputs("Current dir");
Xl.lp = (long *) Mycli->cli_CommandDir;
Xwhile (l.ll) {
X l.ll <<= 2;
X PathName(l.lp[1], buf, 256L);
X puts(buf);
X l.ll = *l.lp;
X }
Xputs("C:");
Xreturn 0;
X}
X
Xdo_pri()
X{
Xint t, pri;
Xstruct Process *proc;
X
Xt=myatoi(av[1],0,20); if (Errno) return 20;
Xpri=myatoi(av[2],-128,127); if (Errno) return 20;
XForbid();
Xproc=(t==0 ? Myprocess : FindCLI((long)t));
Xif (proc==NULL) fprintf(stderr, "process not found\n");
X else SetTaskPri(proc, (long)pri);
XPermit();
Xreturn 0;
X}
X
Xdo_strleft()
X{
Xchar buf[256];
Xint n;
X
Xstrcpy(buf,av[2]);
Xn=myatoi(av[3],1,strlen(buf)); if (Errno) return 20;
Xbuf[n]='\0';
Xset_var(LEVEL_SET, av[1], buf);
Xreturn 0;
X}
X
Xdo_strright()
X{
Xchar buf[256];
Xint n;
X
Xstrcpy(buf, av[2]);
Xn=myatoi(av[3],1,strlen(buf)); if (Errno) return 20;
Xset_var(LEVEL_SET, av[1], buf+strlen(buf)-n);
Xreturn 0;
X}
X
Xdo_strmid()
X{
Xchar buf[256];
Xint n1, n2;
X
Xstrcpy(buf, av[2]);
Xn1=myatoi(av[3],1,strlen(buf))-1; if (Errno) return 20;
Xif (ac>4) {
X n2=myatoi(av[4],1,strlen(buf)-n1);
X if (Errno) return 20;
X buf[n1+n2]='\0';
X }
Xset_var(LEVEL_SET, av[1], buf+n1);
Xreturn 0;
X}
X
Xdo_strlen()
X{
Xchar buf[16];
X
Xsprintf(buf,"%d",strlen(av[2]));
Xset_var(LEVEL_SET, av[1], buf);
Xreturn 0;
X}
X
Xmyatoi(s,min,max)
Xchar *s;
X{
Xlong n;
X
XErrno=0;
Xn=Atol(s);
Xif (Errno==ERRBADINT) ierror(s,511);
X else if (n<min || n>max) {
X Errno=ERRBADINT;
X printf("%s not in (%d,%d)\n",s,min,max);
X }
Xreturn (int)n;
X}
X
Xdo_fltlower()
X{
Xchar buf[256], *s;
X
Xwhile (!CHECKBREAK() && gets(buf)) {
X for (s=buf; *s; s++) *s=tolower(*s);
X puts(buf);
X }
Xreturn 0;
X}
X
Xdo_fltupper()
X{
Xchar buf[256], *s;
X
Xwhile (!CHECKBREAK() && gets(buf)) {
X for (s=buf; *s; s++) *s=toupper(*s);
X puts(buf);
X }
Xreturn 0;
X}
SHAR_EOF
echo "extracting execom.c"
sed 's/^X//' << \SHAR_EOF > execom.c
X/*
X * EXECOM.C
X *
X * Matthew Dillon, 10 August 1986
X * Finally re-written.
X *
X * Version 2.07M by Steve Drew 10-Sep-87
X *
X * Version 3.03A by Carlo Borreo & Cesare Dieni 12-May-89
X *
X */
X
Xextern char *v_histnum, *v_except;
X
X#define F_EXACT 0
X#define F_ABBR 1
X
X#define ST_COND 0x01
X#define ST_NORED 0x02
X#define ST_NOEXP 0x04
X#define ST_AV 0x08 /* delimit args within a variable */
X
Xint has_wild = 0; /* set if any arg has wild card */
X
Xstruct COMMAND {
X int (*func)();
X short minargs;
X short stat;
X int val;
X char *name;
X};
X
Xextern char *format_insert_string();
Xextern char *mpush(), *exarg();
X
Xextern int do_fltupper(), do_fltlower();
Xextern int do_strleft(), do_strright(), do_strmid(), do_strlen();
Xextern int do_fornum(), do_forline(), do_exec();
Xextern int do_diskchange(), do_stack(), do_fault(), do_path(), do_pri();
Xextern int do_rpn(), do_resident(), do_truerun(), do_aset(), do_howmany();
Xextern int do_open(), do_close(), do_fileslist(), do_htype();
Xextern int do_run(), do_number(), do_assign(), do_join();
Xextern int do_quit(), do_set_var(), do_unset_var();
Xextern int do_echo(), do_source(), do_mv(), do_addbuffers();
Xextern int do_cd(), do_pwd(), do_rm(), do_mkdir(), do_history();
Xextern int do_mem(), do_cat(), do_dir(), do_info(), do_inc();
Xextern int do_foreach(), do_return(), do_if(), do_label(), do_goto();
Xextern int do_input(), do_ver(), do_sleep(), do_help();
Xextern int do_strhead(), do_strtail(), do_relabel();
Xextern int do_copy(), date(), do_protect(), do_ps();
Xextern int do_forever(), do_abortline(), do_strings(), do_touch();
Xextern int do_window(), do_search(), do_filenote();
Xchar *push_cpy();
X
Xstatic struct COMMAND Command[] = {
Xdo_run, 0, ST_AV, 0, "\001", /* may call do_source */
Xdo_set_var, 0, 0, LEVEL_ALIAS, "alias", /* uses avline */
Xdo_abortline, 0, 0, 0, "abortline",
Xdo_addbuffers, 2, 0, 0, "addbuffers",
Xdo_aset, 1, 0, 0, "aset",
Xdo_assign, 0, 0, 0, "assign",
Xdo_cat, 0, 0, 0, "cat",
Xdo_cd, 0, 0, 0, "cd",
Xdo_close, 0, 0, 0, "close",
Xdo_copy, 1, 0, 0, "copy",
Xdo_copy, 1, 0, 0, "cp",
Xdate, 0, 0, 0, "date",
Xdo_rm, 0, 0, 0, "delete",
Xdo_dir, 0, ST_NOEXP, 0, "dir",
Xdo_diskchange, 1, 0, 0, "diskchange",
Xdo_inc, 1, 0, -1, "dec",
Xdo_echo, 0, 0, 0, "echo", /* uses avline */
Xdo_if, 0, ST_COND, 1, "else",
Xdo_if, 0, ST_COND, 2, "endif",
Xdo_exec, 1, 0, 0, "exec",
Xdo_fault, 1, 0, 0, "fault",
Xdo_filenote, 2, 0, 0, "filenote",
Xdo_fileslist, 0, 0, 0, "flist",
Xdo_fltlower, 0, 0, 0, "fltlower",
Xdo_fltupper, 0, 0, 0, "fltupper",
Xdo_foreach, 3, ST_NORED, 0, "foreach",
Xdo_forever, 1, ST_NORED, 0, "forever",
Xdo_forline, 3, ST_NORED, 0, "forline",
Xdo_fornum, 4, ST_NORED, 0, "fornum",
Xdo_goto, 1, 0, 0, "goto",
Xdo_help, 0, 0, 0, "help",
Xdo_history, 0, 0, 0, "history",
Xdo_howmany, 0, 0, 0, "howmany",
Xdo_htype, 1, 0, 0, "htype",
Xdo_if, 1, ST_COND|ST_NORED,0, "if",
Xdo_inc, 1, 0, 1, "inc",
Xdo_info, 0, 0, 0, "info",
Xdo_join, 2, 0, 1, "join",
Xdo_input, 1, 0, 0, "input",
Xdo_label, 1, ST_COND, 0, "label",
Xdo_dir, 0, ST_NOEXP, 0, "ls",
Xdo_mkdir, 0, 0, 0, "md",
Xdo_mem, 0, 0, 0, "mem",
Xdo_mkdir, 0, 0, 0, "mkdir",
Xdo_mv, 2, 0, 0, "mv",
Xdo_open, 3, 0, 0, "open",
Xdo_path, 0, 0, 0, "path",
Xdo_pri, 2, 0, 0, "pri",
Xdo_protect, 2, 0, 0, "protect",
Xdo_ps, 0, 0, 0, "ps",
Xdo_pwd, 0, 0, 0, "pwd",
Xdo_quit, 0, ST_NORED, 0, "quit",
Xdo_truerun, 1, ST_NORED, 1, "rback",
Xdo_mv, 2, 0, 0, "rename",
Xdo_relabel, 2, 0, 0, "relabel",
Xdo_resident, 0, 0, 0, "resident",
Xdo_return, 0, 0, 0, "return",
Xdo_rm, 0, 0, 0, "rm",
Xdo_rpn, 0, ST_NOEXP|ST_NORED,0, "rpn",
Xdo_truerun, 1, ST_NORED, 0, "run",
Xdo_search, 2, 0, 0, "search",
Xdo_set_var, 0, ST_AV, LEVEL_SET, "set",
Xdo_sleep, 0, 0, 0, "sleep",
Xdo_source, 0, ST_NORED|ST_AV, 0, "source", /* uses avline */
Xdo_stack, 0, 0, 0, "stack",
Xdo_strhead, 3, 0, 0, "strhead",
Xdo_strings, 1, 0, 0, "strings",
Xdo_strleft, 3, 0, 0, "strleft",
Xdo_strlen, 2, 0, 0, "strlen",
Xdo_strmid, 3, 0, 0, "strmid",
Xdo_strright, 3, 0, 0, "strright",
Xdo_strtail, 3, 0, 0, "strtail",
Xdo_touch, 0, 0, 0, "touch",
Xdo_cat, 0, 0, 0, "type",
Xdo_unset_var, 0, 0, LEVEL_ALIAS, "unalias",
Xdo_unset_var, 0, 0, LEVEL_SET , "unset",
Xdo_ver, 0, 0, 0, "version",
Xdo_window, 0, ST_NOEXP, 0, "window",
X'\0', 0, 0, 0, NULL
X};
X
Xstatic unsigned char elast; /* last end delimeter */
Xstatic char Cin_ispipe, Cout_ispipe;
X
Xexec_command(base)
Xchar *base;
X{
Xregister char *scr;
Xchar buf[32];
X
Xif (!H_stack) {
X add_history(base);
X sprintf(buf, "%d", H_tail_base + H_len);
X set_var(LEVEL_SET, v_histnum, buf);
X }
Xscr = malloc((strlen(base) << 2) + 2);
Xpreformat(base, scr);
Xreturn (fcomm(scr, 1) ? -1 : 1);
X}
X
Xisalphanum(c)
Xregister char c;
X{
Xreturn (
X (c >= '0' && c <= '9') ||
X (c >= 'a' && c <= 'z') ||
X (c >= 'A' && c <= 'Z') ||
X (c == '_')
X );
X}
X
Xpreformat(s, d)
Xregister char *s, *d;
X{
Xregister int si, di, qm;
X
Xsi = di = qm = 0;
Xwhile (s[si] == ' ' || s[si] == 9) ++si;
Xwhile (s[si]) {
X if (qm && s[si] != '\"' && s[si] != '\\') {
X d[di++] = s[si++] | 0x80;
X continue;
X }
X switch (s[si]) {
X case ' ':
X case 9:
X d[di++] = ' ';
X while (s[si] == ' ' || s[si] == 9) ++si;
X if (s[si] == 0 || s[si] == '|' || s[si] == ';') --di;
X break;
X case '*':
X case '?':
X d[di++] = 0x80;
X case '!':
X d[di++] = s[si++];
X break;
X case '#':
X d[di++] = '\0';
X while (s[si]) ++si;
X break;
X case ';':
X case '|':
X d[di++] = s[si++];
X while (s[si] == ' ' || s[si] == 9) ++si;
X break;
X case '\\':
X d[di++] = s[++si] | 0x80;
X if (s[si]) ++si;
X break;
X case '\"':
X qm = 1 - qm;
X ++si;
X break;
X case '^':
X d[di++] = s[++si] & 0x1F;
X if (s[si]) ++si;
X break;
X case '$': /* search end of var name and place false space */
X d[di++] = 0x80;
X d[di++] = s[si++];
X while (isalphanum(s[si])) d[di++] = s[si++];
X d[di++] = 0x80;
X break;
X default:
X d[di++] = s[si++];
X break;
X }
X }
Xd[di++]=0;
Xd[di]=0;
Xif (debug) fprintf (stderr,"PREFORMAT: %d :%s:\n", strlen(d), d);
X}
X
Xextern BPTR extOpen();
X
X/*
X * process formatted string. ' ' is the delimeter.
X *
X * 0: check '\0': no more, stop, done.
X * 1: check $. if so, extract, format, insert
X * 2: check alias. if so, extract, format, insert. goto 1
X * 3: check history or substitution, extract, format, insert. goto 1
X *
X * 4: assume first element now internal or disk based command.
X *
X * 5: extract each ' ' or 0x80 delimited argument and process, placing
X * in av[] list (except 0x80 args appended). check in order:
X *
X * '$' insert string straight
X * '>' setup stdout
X * '>>' setup stdout flag for append
X * '<' setup stdin
X * '*' or '?' do directory search and insert as separate args.
X *
X * ';' 0 '|' end of command. if '|' setup stdout
X * -execute command, fix stdin and out (|) sets
X * up stdin for next guy.
X */
X
X
Xfcomm(str, freeok)
Xregister char *str;
X{
X static int alias_count;
X int p_alias_count = 0;
X char *istr;
X char *nextstr;
X char *command;
X char *pend_alias = NULL;
X char err = 0;
X has_wild = 0;
X
X ++alias_count;
X
X mpush_base();
X if (*str == 0)
X goto done1;
Xstep1:
X if (alias_count == MAXALIAS || ++p_alias_count == MAXALIAS) {
X fprintf(stderr,"Alias Loop\n");
X err = 20;
X goto done1;
X }
X/*
X if (str[1] == '$') {
X if (istr = get_var (LEVEL_SET, str + 2))
X str = format_insert_string(str, istr, &freeok);
X }
X*/
X istr = NULL;
X if (*(unsigned char *)str < 0x80)
X istr = get_var (LEVEL_ALIAS, str); /* only if not \command */
X *str &= 0x7F; /* remove \ teltail */
X if (istr) {
X if (*istr == '%') {
X pend_alias = istr;
X } else {
X str = format_insert_string(str, istr, &freeok);
X goto step1;
X }
X }
X if (*str == '!') {
X char *p, c; /* fix to allow !cmd1;!cmd2 */
X for(p = str; *p && *p != ';' ; ++p);
X c = *p;
X *p = '\0';
X istr = get_history(str);
X *p = c;
X replace_head(istr);
X str = format_insert_string(str, istr, &freeok);
X goto step1;
X }
X nextstr = str;
X command = exarg(&nextstr);
X if (*command == 0)
X goto done0;
X if (pend_alias == 0) {
X if (cmd_stat(command) & ST_COND)
X goto skipgood;
X }
X if (disable || forward_goto) {
X while (elast && elast != ';' && elast != '|')
X exarg(&nextstr);
X goto done0;
X }
Xskipgood:
X {
X register char *arg, *ptr, *scr;
X short redir;
X short doexpand;
X short cont;
X short inc;
X
X ac = 1;
X av[0] = command;
Xstep5: /* ac = nextac */
X if (!elast || elast == ';' || elast == '|')
X goto stepdone;
X
X av[ac] = '\0';
X cont = 1;
X doexpand = redir = inc = 0;
X
X while (cont && elast) {
X int cstat = cmd_stat(command);
X
X ptr = exarg(&nextstr);
X inc = 1;
X arg = "";
X cont = (elast == 0x80);
X switch (*ptr) {
X case '<':
X redir = -2;
X case '>':
X if (cstat & (ST_NORED | ST_COND)) {
X /* don't extract */
X redir = 0; /* <> stuff if its */
X arg = ptr; /* external cmd. */
X break;
X }
X ++redir;
X arg = ptr + 1;
X if (*arg == '>') {
X redir = 2; /* append >> */
X ++arg;
X }
X cont = 1;
X break;
X case '$':
X /* restore args if from set command or pend_alias */
X if ((arg = get_var(LEVEL_SET, ptr + 1)) != NULL) {
X if (cstat & ST_COND) {
X char *tp;
X tp = push_cpy(arg);
X arg = tp;
X }
X else {
X char *pe, sv;
X while (pe = index(arg,0xA0)) {
X sv = *pe;
X *pe = '\0';
X av[ac++] = push_cpy(arg);
X *pe = sv;
X av[ac] = '\0';
X arg = pe+1;
X }
X }
X }
X else
X arg = ptr;
X break;
X case '*':
X case '?':
X if ((cstat & ST_NOEXP) == 0)
X doexpand = 1;
X arg = ptr;
X break;
X default:
X arg = ptr;
X break;
X }
X
X /* Append arg to av[ac] */
X
X for (scr = arg; *scr; ++scr)
X *scr &= 0x7F;
X if (av[ac]) {
X register char *old = av[ac];
X av[ac] = mpush(strlen(arg)+strlen(av[ac]));
X strcpy(av[ac], old);
X strcat(av[ac], arg);
X } else {
X av[ac] = push_cpy(arg);
X }
X if (elast != 0x80)
X break;
X }
X
X /* process expansion */
X
X if (doexpand) {
X char **eav, **ebase;
X int eac;
X has_wild = 1;
X eav = ebase = expand(av[ac], &eac);
X inc = 0;
X if (eav) {
X if (ac + eac + 2 > MAXAV) {
X ierror (NULL, 506);
X err = 1;
X } else {
X QuickSort(eav, eac);
X for (; eac; --eac, ++eav)
X av[ac++] = push_cpy(*eav);
X }
X free_expand (ebase);
X }
X }
X
X /* process redirection */
X
X if (redir && !err) {
X register char *file = (doexpand) ? av[--ac] : av[ac];
X
X if (redir < 0)
X Cin_name = file;
X else {
X Cout_name = file;
X Cout_append = (redir == 2);
X }
X inc = 0;
X }
X
X /* check elast for space */
X
X if (inc) {
X ++ac;
X if (ac + 2 > MAXAV) {
X ierror (NULL, 506);
X err = 1; /* error condition */
X elast = 0; /* don't process any more arguemnts */
X }
X }
X if (elast == ' ')
X goto step5;
X }
Xstepdone:
X av[ac] = '\0';
X
X /* process pipes via files */
X
X if (elast == '|' && !err) {
X static int which; /* 0 or 1 in case of multiple pipes */
X which = 1 - which;
X Cout_name = (which) ? Pipe1 : Pipe2;
X Cout_ispipe = 1;
X }
X
X
X if (err)
X goto done0;
X
X {
X register int i;
X char save_elast;
X char *compile_av();
X register char *avline;
X unsigned char delim = ' ';
X
X save_elast = elast;
X if (pend_alias || (cmd_stat(command) & ST_AV))
X delim = 0xA0;
X avline = compile_av(av,((pend_alias) ? 1 : 0), ac , delim);
X
X
X if (pend_alias) { /* special % alias */
X register char *ptr, *scr;
X for (ptr = pend_alias; *ptr && *ptr != ' '; ++ptr);
X set_var (LEVEL_SET, pend_alias + 1, avline);
X free (avline);
X
X scr = malloc((strlen(ptr) << 2) + 2);
X preformat (ptr, scr);
X fcomm (scr, 1);
X unset_var (LEVEL_SET, pend_alias + 1);
X } else { /* normal command */
X register int ccno;
X long oldcin = Myprocess->pr_CIS;
X long oldcout = Myprocess->pr_COS;
X char *Cin_buf;
X struct FileHandle *ci;
X long oldbuf;
X
X fflush(stdout);
X ccno = find_command (command);
X if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) {
X if (Cin_name) {
X if ((Cin = (long)extOpen(Cin_name,1005L)) == 0L) {
X ierror (NULL, 504);
X err = 1;
X Cin_name = '\0';
X } else {
X Myprocess->pr_CIS = _devtab[stdin->_unit].fd = Cin;
X ci = (struct FileHandle *)(((long)Cin)<<2);
X Cin_buf = (char *)AllocMem(202L, MEMF_PUBLIC);
X oldbuf = ci->fh_Buf;
X if (ci->fh_Buf == 0) /* fexec expects a CIS buffer */
X ci->fh_Buf = (long)Cin_buf>>2;
X }
X }
X if (Cout_name) {
X if (Cout_append && (Cout =(long)extOpen(Cout_name, 1005L)) ) {
X Seek(Cout, 0L, 1L);
X } else {
X Cout = (long)extOpen(Cout_name,1006L);
X }
X if (Cout == NULL) {
X err = 1;
X ierror (NULL, 504);
X Cout_name = '\0';
X Cout_append = 0;
X } else {
X Myprocess->pr_COS = _devtab[stdout->_unit].fd = Cout;
X }
X }
X }
X if (ac < Command[ccno].minargs + 1) {
X ierror (NULL, 500);
X err = -1;
X } else if (!err) {
X i = (*Command[ccno].func)(avline, Command[ccno].val);
X if (i < 0)
X i = 20;
X err = i;
X }
X free (avline);
X if (E_stack == 0 && Lastresult != err) {
X Lastresult = err;
X seterr();
X }
X if ((Command[ccno].stat & (ST_NORED | ST_COND)) == 0) {
X if (Cin_name) {
X fflush(stdin);
X clearerr(stdin);
X ci->fh_Buf = oldbuf;
X extClose(Cin);
X FreeMem(Cin_buf, 202L);
X }
X if (Cout_name) {
X fflush(stdout);
X clearerr(stdout);
X stdout->_flags &= ~_DIRTY; /* because of nil: device */
X extClose(Cout);
X Cout_append = 0;
X }
X }
X Myprocess->pr_CIS = _devtab[stdin->_unit].fd = oldcin;
X Myprocess->pr_COS = _devtab[stdout->_unit].fd = oldcout;
X }
X
X if (Cin_ispipe && Cin_name)
X DeleteFile(Cin_name);
X if (Cout_ispipe) {
X Cin_name = Cout_name; /* ok to assign.. static name */
X Cin_ispipe = 1;
X } else {
X Cin_name = '\0';
X }
X Cout_name = '\0';
X Cout_ispipe = 0;
X elast = save_elast;
X }
X mpop_tobase(); /* free arguments */
X mpush_base(); /* push dummy base */
X
Xdone0:
X {
X char *str;
X if (err && E_stack == 0) {
X str = get_var(LEVEL_SET, v_except);
X if (err >= ((str)?atoi(str):1)) {
X if (str) {
X ++H_stack;
X ++E_stack;
X exec_command(str);
X --E_stack;
X --H_stack;
X } else {
X Exec_abortline = 1;
X }
X }
X }
X if (elast != 0 && Exec_abortline == 0)
X err = fcomm(nextstr, 0);
X Exec_abortline = 0;
X if (Cin_name)
X DeleteFile(Cin_name);
X Cin_name = NULL;
X Cin_ispipe = 0;
X }
Xdone1:
X mpop_tobase();
X if (freeok)
X free(str);
X --alias_count;
X return ((int)err); /* TRUE = error occured */
X}
X
X
Xchar *
Xexarg(ptr)
Xunsigned char **ptr;
X{
X register unsigned char *end;
X register unsigned char *start;
X
X start = end = *ptr;
X while (*end && *end != 0x80 && *end != ';' && *end != '|' && *end != ' ')
X ++end;
X elast = *end;
X *end = '\0';
X *ptr = end + 1;
X return ((char *)start);
X}
X
Xstatic char **Mlist;
X
Xmpush_base()
X{
X char *str;
X
X str = malloc(5);
X *(char ***)str = Mlist;
X str[4] = 0;
X Mlist = (char **)str;
X}
X
Xchar *
Xmpush(bytes)
X{
X char *str;
X
X str = malloc(6 + bytes + 2); /* may need extra 2 bytes in do_run() */
X *(char ***)str = Mlist;
X str[4] = 1;
X Mlist = (char **)str;
X return (str + 5);
X}
X
Xmpop_tobase()
X{
X register char *next;
X while (Mlist) {
X next = *Mlist;
X if (((char *)Mlist)[4] == 0) {
X free (Mlist);
X Mlist = (char **)next;
X break;
X }
X free (Mlist);
X Mlist = (char **)next;
X }
X}
X
X
X/*
X * Insert 'from' string in front of 'str' while deleting the
X * first entry in 'str'. if freeok is set, then 'str' will be
X * free'd
X */
X
Xchar *format_insert_string(str, from, freeok)
Xchar *str;
Xchar *from;
Xint *freeok;
X{
Xregister char *new1, *new2;
Xregister unsigned char *strskip;
Xint len;
X
Xfor (strskip = (unsigned char *)str;
X *strskip && *strskip != ' '
X && *strskip != ';' && *strskip != '|'
X && *strskip != 0x80; ++strskip);
Xlen = strlen(from);
Xnew1 = malloc((len << 2) + 2);
Xpreformat(from, new1);
Xlen = strlen(new1) + strlen(strskip);
Xnew2 = malloc(len+2);
Xstrcpy(new2, new1);
Xstrcat(new2, strskip);
Xnew2[len+1] = 0;
Xfree (new1);
Xif (*freeok) free (str);
X*freeok = 1;
Xreturn new2;
X}
X
Xcmd_stat(str)
Xchar *str;
X{
Xreturn(Command[find_command(str)].stat);
X}
X
Xfind_command(str)
Xchar *str;
X{
Xregister unsigned short i;
Xint len = strlen(str);
X
Xfor (i = 0; Command[i].func; ++i)
X if ( ! strncmp(str, Command[i].name, len)) return (int)i;
Xreturn 0;
X}
X
Xdo_help()
X{
Xregister struct COMMAND *com;
Xint i=0;
X
Xfor (com = &Command[1]; com->func; ++com) {
X printf ("%-12s", com->name);
X if (++i % 6 == 0) printf("\n");
X }
Xprintf("\n");
Xreturn 0;
X}
X
Xchar *push_cpy(s)
Xchar *s;
X{
Xreturn strcpy(mpush(strlen(s)), s);
X}
SHAR_EOF
echo "End of archive 1 (of 2)"
# if you want to concatenate archives, remove anything after this line
exit